1. 사용할 라이브러리

R의 필수적이고 기초적인 문법들을 한번에 싹 어셈블리해보자.~(그렇게 거창하게는 아니고…)~

install.packages("Deriv")
library(Deriv)
Updating HTML index of packages in '.Library'

Making 'packages.html' ...
 done

2. 기초

A. 기본기 중의 기본기


- 원래 응당 헬로우 월드부터 하는 게 옳기는 하나… ~우리 그럴 레벨 아니잖아요?~

그래도 해보자!

print("hello world!")
[1] "hello world!"
- rm(list = ls())
  • 기존에 저장된 변수나 함수들을 전부 지우고 가볍게 시작한다. R의 경우는 프로그램을 종요해도 로그가 캐시로 남아있기 때문에…(그정도까진 아님) 분석 시작 때에 사용하면 용이하다.
rm(list = ls())

R-studio등에서 실습하고 있다면, environment탭의 Data가 전부 깔끔하게 비워지는 것을 볼 수 있다…

- 연산
  • 다른 프로그램에서 하는 것과 그냥 거의 동일하다고 보면 된다. 다른 것이나 몇 가지 추가된 게 있긴 하지만…(잘 안쓰니까)
123 + 456 ## 더하기
579
164 - 111 ## 빼기
53
5*113  ## 곱하기
565
12/4  ## 나누기
3
2**6  ## 제곱
64
  • 이 아래부터는 파이썬과 다르게 써야 한다…
13%%4  ## 나머지, 안타깝게도 그냥 %이 아니다...
1
13%/%4  ## 몫, 정말 안타깝게도 그냥 //이 아니다...
3
2^6  ## 제곱의 다른 형태, 이건 그냥 알아만 두자.
64
- 벡터, 리스트, 배열
  • 벡터

가장 기본적인 데이터 저장 방식이다. 이쪽이 어떻게 보면 다른 언어에서의 리스트와 가깝다.

c(1,2,5,8)  ## 직접 지정
  1. 1
  2. 2
  3. 5
  4. 8
c(1:10)  ## 순서대로
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
c(1, '2', 3, 4)  ## 저장 형식은 다를 수 없음
  1. '1'
  2. '2'
  3. '3'
  4. '4'
  • 리스트

사실상 딕셔너리라고 봐도 무방하다. 원소로 key와 value를 넣을 수 있고, 그 안에 또 key와 value를 넣는 등의 작업이 가능하다. value에는 어떠한 형태든 다 들어갈 수 있다.

대괄호로 리스트를 지정하는 것은 불가능하다. 대괄호는 인덱싱에서만 사용할 수 있다…

lst <- list(a = c(1,2,3),'b',c = list('a', 'b', c = list(1,2,3)))
lst$a
lst['a']
  1. 1
  2. 2
  3. 3
$a =
  1. 1
  2. 2
  3. 3
lst[['c']][['c']]
  1. 1
  2. 2
  3. 3

호출은 대괄호[]나, 달러표시$를 이용하면 된다. 대괄호를 하나 더 넣어서 호출하면 내부 값만을 호출한다.

  • 배열

파이썬에선 배열이나 행렬을 구현하기 위해서 따로 라이브러리를 들여오거나 함수를 구축해야만 했다. 하지만 R에선 자체적으로 행렬을 구현해놨다.

array(1:6, dim = c(2,3), dimnames = list(c(1,2),c('a','b','c')))
A matrix: 2 × 3 of type int
a b c
1 1 3 5
2 2 4 6
array(1:9, dim = c(3,3))[1:2, 2:3]  ## 슬라이싱도 가능
A matrix: 2 × 2 of type int
4 7
5 8

데이터 프레임마냥 행과 열에 이름도 붙일 수 있다.(사실상 데이터프레임이나 다름없긴 함)

- 변환함수, 생성(?)함수

수학적 변환이나 통계적 변환, 또는 벡터 등을 생성하는 함수들을 알아보자.

  • 수학함수
sin(pi/2)  ## asin()도 있다. pi는 기본적으로 원주율이다.
cos(pi)    ## acos()
tan(pi/4)  ## atan()
1
-1
1
exp(1)  ## 지수함수
log(49, base = 7)  ## 디폴트는 자연로그(base = exp(1))
sqrt(64)  ## 그냥 64**0.5를 해도 무방하긴 함...
2.71828182845905
2
8
  • 집계함수

먼저 아래와 같은 벡터가 있다고 하면…

x <- c(1,2,3,3,3,4,5)
mean(x)  ## 평균
sd(x)    ## 표준편차
var(x)   ## 분산
max(x)   ## 최댓값
median(x)  ## 중간값
min(x)   ## 최솟값
length(x)  ## 길이
3
1.29099444873581
1.66666666666667
5
3
1
7

최빈값은 모듈로 없다.

  • 생성(?)함수
seq(from = 1, to = 10, by = 2)  ## 수열, 간격 지정
seq(1, 10, length = 4)  ## 갯수 지정
rep('a', 5)  ## 반복
  1. 1
  2. 3
  3. 5
  4. 7
  5. 9
  1. 1
  2. 4
  3. 7
  4. 10
  1. 'a'
  2. 'a'
  3. 'a'
  4. 'a'
  5. 'a'
- 행렬과 데이터프레임
  • 행렬
matrix(1:9, nrow = 3, byrow = FALSE)  ## byrow의 디폴트는 FALSE이다.
A matrix: 3 × 3 of type int
1 4 7
2 5 8
3 6 9

벡터 데이터를 가져와서 행이나 열의 갯수를 정해주면 행렬이 나온다.

A <- matrix(c(1,7,3,8,9,11,2,3,21), nrow = 3, byrow = TRUE)
dim(A)  ## 차원
nrow(A)  ## 행의 갯수
ncol(A)  ## 열의 갯수
diag(A)  ## 대각원소, 역으로 대각행렬을 산출할 수도 있음.
  1. 3
  2. 3
3
3
  1. 1
  2. 9
  3. 21
t(A)  ## transition
det(A)  ## determinant
solve(A)  ## inverse matrix
round(A%*%solve(A), 5)  ## 행렬곱
A matrix: 3 × 3 of type dbl
1 8 2
7 9 3
3 11 21
-847.999999999999
A matrix: 3 × 3 of type dbl
-0.183962264 0.16273585 -0.05896226
0.172169811 -0.01768868 -0.01533019
-0.007075472 -0.01297170 0.05542453
A matrix: 3 × 3 of type dbl
1 0 0
0 1 0
0 0 1
cbind(A, solve(A))  ## 열로 concat
rbind(A, solve(A))  ## 행으로 concat
A matrix: 3 × 6 of type dbl
1 7 3 -0.183962264 0.16273585 -0.05896226
8 9 11 0.172169811 -0.01768868 -0.01533019
2 3 21 -0.007075472 -0.01297170 0.05542453
A matrix: 6 × 3 of type dbl
1.000000000 7.00000000 3.00000000
8.000000000 9.00000000 11.00000000
2.000000000 3.00000000 21.00000000
-0.183962264 0.16273585 -0.05896226
0.172169811 -0.01768868 -0.01533019
-0.007075472 -0.01297170 0.05542453
rownames(A) <- c('row1', 'row2', 'row3')  ## 잘 안씀
colnames(A) <- c('col1','col2','col3')
A
A matrix: 3 × 3 of type dbl
col1 col2 col3
row1 1 7 3
row2 8 9 11
row3 2 3 21
- 분포

분포마다 파라미터는 조금씩 다르지만, 함수의 이름이 지어지는 원리는 동일하다.

  • output random number(분포에 따른 무작위 숫자 산출)
rnorm(n = 1, mean = 0, sd = 1)  ## 표준정규분포
rt(n = 1, df = 8)  ## t분포
runif(n = 1, min = 0, max = 1)  ## 균일분포
rchisq(n = 1, df = 50)  ## 카이제곱분포
rf(n = 1, df1 = 5, df2 = 20)  ## f분포
rbinom(n = 10, size = 5, prob = 0.5)  ## 이항분포
rpois(n = 1, lambda = 5)  ## 포아송분포
rexp(n = 1, rate = 5)  ## 지수분포
rgamma(n = 1, shape = 1, rate = 5)  ## 감마분포(사실상 지수분포)
## 등등...
-0.235364223846143
1.40491627566088
0.0678379517048597
67.1548649869233
0.826528465359129
  1. 3
  2. 2
  3. 3
  4. 3
  5. 2
  6. 2
  7. 3
  8. 3
  9. 4
  10. 2
5
0.409051089344506
0.156511356764008
  • 확률밀도함수의 y값 산출(probability Density function)
dnorm(x = 0, mean = 0, sd = 1)  ## pdf의 y값, 여긴 x를 넣음
0.398942280401433
  • 누적분포함수의 y값 산출(Probability distribution function)
pnorm(q = 0, mean = 0, sd = 1)  ## 여긴 quantile값을 넣어야 한다.
0.5
  • 좌측 면적에 따른 분위수(Quantile) 산출
qnorm(p = 0.05, mean = 0, sd = 1, lower.tail = FALSE)  ## 확률을 넣어준다.
1.64485362695147

기본적으로 좌측 면적부터 취급하므로, lower.tail옵션을 FALSE로 택해 우측 면적을 기준으로 구할 수 있다.

- 로직

기본적으로 논리연산자를 이용한다.

x <- c(1,3,4,8,9)
x < 4  ## 해당하는 값은 True
x <= 4
!(x < 4)  ## 여집합
x == 4
x != 4
  1. TRUE
  2. TRUE
  3. FALSE
  4. FALSE
  5. FALSE
  1. TRUE
  2. TRUE
  3. TRUE
  4. FALSE
  5. FALSE
  1. FALSE
  2. FALSE
  3. TRUE
  4. TRUE
  5. TRUE
  1. FALSE
  2. FALSE
  3. TRUE
  4. FALSE
  5. FALSE
  1. TRUE
  2. TRUE
  3. FALSE
  4. TRUE
  5. TRUE
x > 3 | x <= 4  ## or
x > 3 & x <= 4  ## and
  1. TRUE
  2. TRUE
  3. TRUE
  4. TRUE
  5. TRUE
  1. FALSE
  2. FALSE
  3. TRUE
  4. FALSE
  5. FALSE
which(x>3 & x<=4)  ## 몇 번째 값이 True인가?
3

which()함수를 이용하여 조건에 맞는 슬라이싱을 할 수 있다.

x[which(x>3 & x<=4)]
4
- 조건문